home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library / Microsoft Programmer's Library (CD-ROM Database)(125-099-008)(Version 1.1a)(CDRM 162100)(1989).iso / SAMPCODE / OS2SDK11 / TK4 / OPENDLG / FILE1.C < prev    next >
C/C++ Source or Header  |  1989-02-20  |  17KB  |  582 lines

  1. /*
  2.     FILE1.C -- Dialog Directory Listbox and Open File functions
  3.     Created by Microsoft Corporation, 1989
  4. */
  5.  
  6. #define  INCL_DOS
  7. #include "tool.h"
  8.  
  9. /****************************************************************************\
  10. * This function builds a directory list in a list box.
  11. \****************************************************************************/
  12.  
  13. int FAR PASCAL DlgDirList(hwnd, lpszPath, idDirList, idFileList,
  14.                           idStaticPath, attr)
  15. HWND hwnd;
  16. PSZ  lpszPath;
  17. int idDirList;
  18. int idFileList;
  19. int idStaticPath;
  20. USHORT attr;
  21.     {
  22.     CHAR szPath[MAX_FNAME_LEN];
  23.     CHAR chTmp;
  24.     PSZ  lpszFile, lpszNull;
  25.     HPOINTER hPointer;
  26.  
  27.     /* ensure path is legal and expand to full search path */
  28.     if (!DlgParseFile(lpszPath, (PSZ)szPath, FALSE, TRUE))
  29.         return FALSE;
  30.  
  31.     /* set pointer to hours glass */
  32.     hPointer = WinQueryPointer(HWND_DESKTOP); 
  33.     WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
  34.  
  35.     /* set current drive */
  36.     DosSelectDisk(*szPath - 'A' + 1);
  37.  
  38.     /* temporarily put zero after directory spec and set current directory */
  39.     lpszFile = FileInPath((PSZ)szPath);
  40.     lpszNull = lpszFile;
  41.     if (lpszNull > (PSZ)szPath + 3)
  42.         lpszNull--;
  43.     chTmp = *lpszNull;
  44.     *lpszNull = '\0';
  45.     DosChDir((PSZ)szPath, 0l);
  46.     if (idStaticPath)
  47.         WinSetWindowText(WinWindowFromID(hwnd, idStaticPath),
  48.                          DlgFitPathToBox(hwnd, idStaticPath, (PSZ)szPath));
  49.     *lpszNull = chTmp;
  50.  
  51.     /* fill list box with file names */
  52.     if (idDirList && idFileList)
  53.         {
  54.         /* fill them up with new entries */
  55.         DlgFillListBoxes(hwnd, idDirList, idFileList, attr, lpszFile);
  56.         }
  57.  
  58.     /* reset pointer to previous figure */
  59.     WinSetPointer(HWND_DESKTOP, hPointer);
  60.  
  61.     return TRUE;
  62.     }
  63.  
  64.  
  65.  
  66.  
  67. /****************************************************************************\
  68. * This function gets the file name selected by the user.
  69. \****************************************************************************/
  70.  
  71. int FAR PASCAL DlgDirSelect(hwnd, lpszIn, idListBox)
  72. HWND hwnd;
  73. PSZ  lpszIn;
  74. int idListBox;
  75.     {
  76.     CHAR sz[MAX_FNAME_LEN];
  77.     int item;
  78.     PSZ  lpsz, lpszFile;
  79.     BOOL fDir;
  80.  
  81.     /* get currently selected list entry */
  82.     item = (int) WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYSELECTION, 0L, 0L);
  83.     if (item == LIT_NONE)
  84.         return FALSE;
  85.     WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYITEMTEXT,
  86.                       MPFROM2SHORT(item, MAX_FNAME_LEN), (MPARAM)(PSZ)sz);
  87.     lpszFile = sz;
  88.  
  89.     /* extract name */
  90.     if (fDir = (*sz == '['))
  91.         {
  92.         lpszFile = NextChar(lpszFile);
  93.         if (*lpszFile == '-')
  94.             {
  95.             /* drive selection */
  96.             lpszFile = NextChar(lpszFile);
  97.             *(lpszFile+1) = ':';
  98.             *(lpszFile+2) = '\0';
  99.             }
  100.         else
  101.             {
  102.             /* directory selection */
  103.             lpsz = lpszFile;
  104.             while (*lpsz != ']')
  105.                 lpsz = NextChar(lpsz);
  106.             *lpsz = '\\';
  107.             }
  108.         }
  109.  
  110.     lstrcpy(lpszIn, lpszFile);
  111.     return (fDir);
  112.     }
  113.  
  114.  
  115.  
  116.  
  117. /****************************************************************************\
  118. * This function tries to open pdlf=>szFileName.  If the file does not
  119. * exist, the function asks to create it.
  120. *
  121. *  Returns:
  122. *    TDF_NOOPEN  - Illegal Filename or user didn't want to create
  123. *    TDF_OLDOPEN - Existing file
  124. *    TDF_NEWOPEN - File was created
  125. \****************************************************************************/
  126.  
  127. USHORT PASCAL DlgOpenFile(pdlf, hwnd)
  128. PDLF pdlf;
  129. HWND hwnd;
  130.     {
  131.     /* check for legal dos name */
  132.     if (!DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
  133.                       FALSE, FALSE))
  134.         {
  135.         DlgAlertBox(hwnd, IDS_IFN, pdlf, MB_OK | MB_ICONEXCLAMATION);
  136.         return (TDF_NOOPEN);
  137.         }
  138.     /* see if file already exists */
  139.     if (DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
  140.                       TRUE, FALSE))
  141.         {
  142.         if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
  143.                         (PSZ)pdlf->szOpenFile, OF_READ))
  144.             return (TDF_OLDOPEN);
  145.         else
  146.             {
  147.             DlgAlertBox(hwnd, IDS_EOF, pdlf, MB_OK | MB_ICONEXCLAMATION);
  148.             return (TDF_NOOPEN);
  149.             }
  150.         }
  151.     /* file doesn't exist: create new one? */
  152.     else if (DlgAlertBox(hwnd, IDS_FNF, pdlf, MB_YESNO | MB_ICONQUESTION) == MBID_YES)
  153.         {
  154.         if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
  155.                         (PSZ)pdlf->szOpenFile, OF_CREATE))
  156.             return (TDF_NEWOPEN);
  157.         else
  158.             DlgAlertBox(hwnd, IDS_ECF, pdlf, MB_OK | MB_ICONEXCLAMATION);
  159.         }
  160.     return(TDF_NOOPEN);
  161.     }
  162.  
  163.  
  164.  
  165.  
  166. /****************************************************************************\
  167. * This function returns the OS/2 file handle if operation is successful,
  168. * 0 otherwise.
  169. *
  170. * Effects:  Depend on wMode:
  171. *     OF_READ:      open file for reading only
  172. *     OF_WRITE:     open file for writing only
  173. *     OF_READWRITE: open file for reading and writing
  174. *     OF_CREATE:    create the file if it does not exist
  175. *     OF_REOPEN:    open file using info in the reopen buffer
  176. *     OF_EXIST:     test file existence
  177. *     OF_PARSE:     fill reopen buffer, with no other action
  178. \****************************************************************************/
  179.  
  180.  
  181. BOOL CALLBACK OpenFile(lpszFile, lpHandle, lpszOpenFile, wMode)
  182. PSZ  lpszFile;
  183. PHFILE lpHandle;
  184. PSZ  lpszOpenFile;
  185. USHORT wMode;
  186.     {
  187.     HFILE hFile = NULL;
  188.     USHORT wAction = NULL;
  189.     USHORT wAttrs = NULL;
  190.     USHORT wOpenFlag, wOpenMode;
  191.     CHAR sz[MAX_FNAME_LEN];
  192.  
  193.     /* if reopen specified, use earlier pathname */
  194.     if (wMode & OF_REOPEN)
  195.         {
  196.         lstrcpy((PSZ)sz, lpszOpenFile);
  197.         lpszFile = (PSZ)sz;
  198.         }
  199.  
  200.     /* parse file */
  201.     if (!DlgParseFile(lpszFile, lpszOpenFile, wMode&OF_EXIST, FALSE))
  202.         {
  203.         *lpszOpenFile = '\0';
  204.         return FALSE;
  205.         }
  206.     /* return if implementing boolean test OF_PARSE or OF_EXIST */
  207.     if (wMode & (OF_PARSE | OF_EXIST))
  208.         {
  209.         return TRUE;
  210.         }
  211.  
  212.     if (wMode & OF_READ)
  213.         {
  214.         wOpenFlag = 0x01;               /* fail if it doesn't exist */
  215.         wOpenMode = 0x20;               /* read only */
  216.         }
  217.     else if (wMode & OF_WRITE)
  218.         {
  219.         wOpenFlag = 0x11;               /* create if necessary */
  220.         wOpenMode = 0x11;               /* write only */
  221.         }
  222.     else if (wMode & OF_READWRITE)
  223.         {
  224.         wOpenFlag = 0x11;               /* create if necessary */
  225.         wOpenMode = 0x12;               /* read-write */
  226.         }
  227.     else if (wMode & OF_CREATE)
  228.         {
  229.         /* create and close file */
  230.         wOpenFlag = 0x10;               /* fail if exists */
  231.         wOpenMode = 0x10;               /* read only */
  232.         }
  233.     else
  234.         {
  235.         return FALSE;
  236.         }
  237.  
  238.     if (DosOpen(lpszFile, (PHFILE)&hFile, &wAction,
  239.                 (ULONG) 0, 0, wOpenFlag, wOpenMode, (ULONG) 0))
  240.         return FALSE;
  241.  
  242.     if (wMode & OF_CREATE)
  243.         {
  244.         if (DosClose(hFile))
  245.             return FALSE;
  246.         }
  247.     else
  248.         *lpHandle = hFile;
  249.  
  250.     return TRUE;
  251.     }
  252.  
  253.  
  254.  
  255.  
  256. /****************************************************************************\
  257. * This function puts a path string into a static box.
  258. \****************************************************************************/
  259.  
  260. PSZ  PASCAL DlgFitPathToBox(hwnd, idStatic, lpch)
  261. HWND hwnd;
  262. int idStatic;
  263. PSZ  lpch;
  264.     {
  265.     WRECT rc;
  266.     int cxField;
  267.     char chDrive;
  268.     HPS hps;
  269.  
  270.     /* get length of static field */
  271.     WinQueryWindowRect(WinWindowFromID(hwnd, idStatic), (PRECTL)&rc);
  272.     cxField = rc.xRight - rc.xLeft;
  273.  
  274.     hps = WinGetPS(hwnd);
  275.     if (cxField < LOUSHORT(GetTextExtent(hps, lpch,
  276.                                            lstrlen(lpch))))
  277.         {
  278.         chDrive = *lpch;
  279.         /* chop characters off front of string until text is short enough */
  280.         do
  281.             do
  282.                 lpch = NextChar(lpch);
  283.             while (*(lpch+6) != '\\' &&
  284.                    *(lpch+6) != '\0');
  285.         while (cxField < LOUSHORT(GetTextExtent(hps, lpch,
  286.                                                  lstrlen(lpch))));
  287.         /* insert header */
  288.         *lpch++ = chDrive;
  289.         *lpch++ = ':';
  290.         *lpch++ = '\\';
  291.         *lpch++ = '.';
  292.         *lpch++ = '.';
  293.         *lpch++ = '.';
  294.         lpch -= 6;
  295.         }
  296.     WinReleasePS(hps);
  297.     return (lpch);
  298.     }
  299.  
  300.  
  301.  
  302.  
  303. /****************************************************************************\
  304. * This function fills a list box with appropriate file names from the
  305. * current directory.
  306. \****************************************************************************/
  307.  
  308. int PASCAL DlgFillListBoxes(hwnd, idDirList, idFileList, attr, lpszFileSpec)
  309. HWND   hwnd;
  310. int    idDirList;
  311. int    idFileList;
  312. USHORT attr;
  313. PSZ    lpszFileSpec;
  314.     {
  315.     USHORT usFiles, usDrive;
  316.     int i;
  317.     PSZ  lpsz;
  318.     HDIR hDir;
  319.     ULONG lrgfDrives;
  320.     FILEFINDBUF ffb;
  321.     CHAR sz[20];
  322.     int cDrives;
  323.     int result = -1;
  324.     HWND hwndFiles, hwndDirs;
  325.  
  326.     /* get listbox window handles */
  327.     hwndFiles = WinWindowFromID(hwnd, idFileList);
  328.     hwndDirs = WinWindowFromID(hwnd, idDirList);
  329.  
  330.     /* disable updates to listboxes */
  331.     WinEnableWindowUpdate(hwndFiles, FALSE);
  332.     WinEnableWindowUpdate(hwndDirs, FALSE);
  333.  
  334.     /* empty list boxes of any old entries */
  335.     WinSendMsg(hwndFiles, LM_DELETEALL, 0L, 0L);
  336.     WinSendMsg(hwndDirs, LM_DELETEALL, 0L, 0L);
  337.  
  338.     /* put files that lMatch search spec in file listbox */
  339.     usFiles = 1;
  340.     hDir = 0xFFFF;
  341.     if (!DosFindFirst(lpszFileSpec, (PHDIR)&hDir,
  342.         attr&~(BITATTRDIR|BITATTRDRIVE), (PFILEFINDBUF)&ffb, sizeof(FILEFINDBUF),
  343.         &usFiles, 0L))
  344.         {
  345.         do
  346.             {
  347.             /* add string to list box */
  348.             result = (int) WinSendMsg(hwndFiles, LM_INSERTITEM,
  349.                                       MPFROM2SHORT(LIT_SORTASCENDING, 0),
  350.                                       (MPARAM)(PSZ)&(ffb.achName[0]));
  351.             usFiles = 1;
  352.             }
  353.         while (result >= 0 && !DosFindNext(hDir,
  354.                                            (PFILEFINDBUF)&ffb,
  355.                                            sizeof(FILEFINDBUF),
  356.                                            &usFiles));
  357.         DosFindClose(hDir);
  358.         }
  359.  
  360.     if (result != LIT_MEMERROR && (attr   & BITATTRDIR))
  361.         {
  362.         /* get directories */
  363.         usFiles = 1;
  364.         hDir = 0xFFFF;
  365.     if (!DosFindFirst((PSZ)szStarStar, (PHDIR)&hDir, BITATTRDIR,
  366.             (PFILEFINDBUF)&ffb, sizeof(FILEFINDBUF), &usFiles, 0l))
  367.             {
  368.             do
  369.                 {
  370.                 /* extract file name */
  371.                 if (ffb.attrFile & BITATTRDIR)
  372.                     {
  373.                     /* put brackets around directory */
  374.             lpsz = (PSZ)&(ffb.achName[0]);
  375.                     if (*lpsz == '.' && *(lpsz+1) == '\0')
  376.                         /* forget about current directory name '.' */
  377.             continue;
  378.                     sz[0] = '[';
  379.                     lstrcpy((PSZ)&sz[1], lpsz);
  380.                     sz[ffb.cchName    + 1] = ']';
  381.                     sz[ffb.cchName    + 2] = '\0';
  382.                     lpsz = (PSZ)sz;
  383.                     /* add string to list box */
  384.                     result = (int) WinSendMsg(hwndDirs, LM_INSERTITEM,
  385.                                               MPFROM2SHORT(LIT_SORTASCENDING, 0),
  386.                                               (MPARAM)lpsz);
  387.                     }
  388.                 usFiles = 1;
  389.                 }
  390.             while (result >= -1 && !DosFindNext(hDir,
  391.                                                (PFILEFINDBUF)&ffb,
  392.                                                sizeof(FILEFINDBUF),
  393.                                                &usFiles));
  394.             DosFindClose(hDir);
  395.             }
  396.         }
  397.  
  398.     if (result != LIT_MEMERROR && (attr   & BITATTRDRIVE))
  399.         /* get drives */
  400.         {
  401.         sz[0] = '[';
  402.         sz[1] = sz[3] = '-';
  403.         sz[4] = ']';
  404.         sz[5] = '\0';
  405.  
  406.         DosQCurDisk(&usDrive, (unsigned long far *)&lrgfDrives);
  407.         cDrives = 0;
  408.         for (i=0; 'A' + i <= 'Z'; i++)
  409.             {
  410.             if (lrgfDrives & 1L)
  411.                 {
  412.                 sz[2] = (char)('A' + i);
  413.                 /* add drive to list */
  414.                 result = (int) WinSendMsg(hwndDirs, LM_INSERTITEM,
  415.                       MPFROM2SHORT(LIT_END, 0),
  416.                                           (MPARAM)(PSZ)sz);
  417.                 cDrives++;
  418.                 }
  419.             lrgfDrives >>= 1;
  420.             }
  421.         }
  422.  
  423.     /* enable and show updated listboxes */
  424.     WinShowWindow(hwndFiles, TRUE);
  425.     WinShowWindow(hwndDirs, TRUE);
  426.  
  427.     return result;
  428.     }
  429.  
  430.  
  431.  
  432.  
  433. /****************************************************************************\
  434. * This function parses a string into an fully expanded file name or search
  435. * path.  If fExist is true then the file must exist or the search path must
  436. * correspond to at least one existing file.  In all cases, the corresponding
  437. * directory must exist.  The string must be a file name, ie. no wildcards,
  438. * unless fWildOkay is true.  Returns TRUE if string is parsed correctly.
  439. \****************************************************************************/
  440.  
  441. BOOL PASCAL DlgParseFile(lpszIn, lpszExp, fExist, fWildOkay)
  442. PSZ  lpszIn, lpszExp;
  443. BOOL fExist, fWildOkay;
  444.     {
  445.     CHAR szPath[MAX_FNAME_LEN];
  446.     PSZ  lpszFile, lpsz;
  447.  
  448.     /* go past any path spec to first char in file name */
  449.     lpszFile = FileInPath(lpszIn);
  450.  
  451.     /* check validity of file name */
  452.     if (!fExist && !DlgValidName(lpszFile, fWildOkay))
  453.         {
  454.         *lpszExp = '\0';
  455.         return FALSE;
  456.         }
  457.  
  458.     /* copy path part to path string */
  459.     lpsz = (PSZ)szPath;
  460.     if (lpszIn == lpszFile)
  461.         *lpsz++ = '.';
  462.     else
  463.         {
  464.         while (lpszIn < lpszFile && lpsz < ((PSZ)szPath + MAX_FNAME_LEN - 1))
  465.             *lpsz++ = *lpszIn++;
  466.         }
  467.     *lpsz = '\0';
  468.  
  469.     /* let DOS do the dirty work */
  470.     if (fExist)
  471.         {
  472.         /* test existence of file while parsing path */
  473.         if (DosSearchPath(0, (PSZ)szPath, lpszFile, lpszExp, MAX_FNAME_LEN))
  474.             {
  475.             *lpszExp = '\0';
  476.             return FALSE;
  477.             }
  478.         }
  479.     else
  480.         {
  481.         /* use dummy wild card while parsing path */
  482.     if (DosSearchPath(0, (PSZ)szPath, (PSZ)szStarStar, lpszExp, MAX_FNAME_LEN))
  483.             {
  484.             *lpszExp = '\0';
  485.             return FALSE;
  486.             }
  487.         /* replace wild card part with true file name converted to CAPS */
  488.         lpsz = lpszExp;
  489.         while (*lpsz != '?' && *lpsz != '*' && *lpsz != '\0')
  490.             lpsz++;
  491.         while (*lpszFile != '\0')
  492.             {
  493.             *lpsz++ = *lpszFile++;
  494.             }
  495.         *lpsz = '\0';
  496.         Upper(lpszExp);
  497.         }
  498.     return TRUE;
  499.     }
  500.  
  501.  
  502.  
  503.  
  504. /****************************************************************************\
  505. * This function determines if a string forms a legal file name or search
  506. * path.  Wildcard characters are acceptable if fWildOkay is true.  Returns
  507. * TRUE if string is legal.
  508. \****************************************************************************/
  509.  
  510. BOOL PASCAL DlgValidName(lpszName, fWildOkay)
  511. PSZ  lpszName;
  512. BOOL fWildOkay;
  513.     {
  514.     int cLen;
  515.     PSZ  lpsz;
  516.  
  517.     /* check file name */
  518.     if (*lpszName == '\0')
  519.         return FALSE;
  520.     cLen = 0;
  521.     lpsz = lpszName;
  522.     while (*lpsz != '\0' && *lpsz != '.')
  523.         {
  524.         if (++cLen > 8 || *lpsz < 0x20)
  525.             return FALSE;
  526.         switch (*lpsz++)
  527.             {
  528.             case '*':
  529.             case '?':
  530.                 if (fWildOkay)
  531.                     break;
  532.             case '\"':
  533.             case '\\':
  534.             case '/':
  535.             case '[':
  536.             case ']':
  537.             case ':':
  538.             case '|':
  539.             case '<':
  540.             case '>':
  541.             case '+':
  542.             case '=':
  543.             case ';':
  544.             case ',':
  545.                 return FALSE;
  546.             }
  547.         }
  548.  
  549.     /* check extension */
  550.     if (*lpsz++ == '\0')
  551.         return TRUE;
  552.     cLen = 0;
  553.     while (*lpsz != '\0')
  554.         {
  555.         if (++cLen > 3 || *lpsz < 0x20)
  556.             return FALSE;
  557.         switch (*lpsz++)
  558.             {
  559.             case '*':
  560.             case '?':
  561.                 if (fWildOkay)
  562.                     break;
  563.             case '.':
  564.             case '\"':
  565.             case '\\':
  566.             case '/':
  567.             case '[':
  568.             case ']':
  569.             case ':':
  570.             case '|':
  571.             case '<':
  572.             case '>':
  573.             case '+':
  574.             case '=':
  575.             case ';':
  576.             case ',':
  577.                 return FALSE;
  578.             }
  579.         }
  580.     return TRUE;
  581.     }
  582.